#pragma once

#include "../../inc/TopoDS/OMIT_MeshForwardDecl.h"

namespace OMIT_NAMESPACE
{
	template<typename Traits>
	class TVert
    {
	public:
		using TV = MeshTraits_V<Traits>;
		using TE = MeshTraits_E<Traits>;
		using TF = MeshTraits_F<Traits>;
		using TH = MeshTraits_H<Traits>;

	public:
		TH* HalfEdge() noexcept { return _h; }
		const TH* HalfEdge() const noexcept { return const_cast<TVert*>(this)->HalfEdge(); }

		void SetHalfEdge(TH* h) noexcept { _h = h; }

		void Reset() noexcept { _h = nullptr; }

        // 关联的半边为空指针
		bool IsIsolated() const noexcept { return !_h; }

        // 顶点在边上 === 半边关联的面在边界上（空指针）
		bool IsOnBoundary() const noexcept;

        // 按照旋转后继的方式遍历从 this 朝外的半边
        // 左闭右开：[h, h.RotateNext(), h.RotateNext().RotateNext(), ..., he)
        H_RotaView<false, Traits> OutHalfEdges();
		H_RotaView<true, Traits> OutHalfEdges() const;

		V_VertView<false, Traits> AdjVertices();
		V_VertView<true, Traits> AdjVertices() const;

		V_EdgeView<false, Traits> AdjEdges();
		V_EdgeView<true, Traits> AdjEdges() const;

        // 顶点的度，为邻接的边的数量
		std::size_t Degree() const noexcept;

        // 获得从 this 到 end 的半边，如果不存在返回空指针
		TH* HalfEdgeTo(TV* end) noexcept;
		const TH* HalfEdgeTo(const TV* end) const noexcept
		{ return const_cast<TVert*>(this)->HalfEdgeTo(const_cast<TV*>(end)); }

        // 获得从 start 到 end 的半边，如果不存在返回空指针
		static TH* HalfEdgeAlong(TV* start, Traits* end) noexcept { return start->HalfEdgeTo(end); }
		static const TH* HalfEdgeAlong(const TV* start, const TV* end) noexcept
		{ return HalfEdgeAlong(const_cast<TV*>(start), const_cast<TV*>(end)); }

        // 获得从 this 到 v 的边，如果不存在返回空指针
		TE* EdgeWith(TV* v) noexcept;
		const TE* EdgeWith(const TV* v) const noexcept { return const_cast<TVert*>(this)->EdgeWith(const_cast<TV*>(v)); }

        // 获得从 v0 到 v1 的边，如果不存在返回空指针
		static TE* EdgeBetween(TV* v0, TV* v1) noexcept { return v0->EdgeWith(v1); }
		static const TE* EdgeBetween(const TV* v0, const TV* v1) noexcept
		{ return EdgeBetween(const_cast<TV*>(v0), const_cast<TV*>(v1)); }

        // 判断 this 和 v1 之间是否存在边
		bool IsConnectedWith(const TV* v) const noexcept { return EdgeWith(v); }
        // 判断 v0 和 v1 之间是否存在边
		static bool IsConnected(const TV* v0, const TV* v1) noexcept { return v0->IsConnectedWith(v1); }

	private:
		friend TMesh<Traits>;
		TH* FindFreeIncident() noexcept;

		TH* _h{ nullptr };
	};
}

#include "../../inc/TopoDS/OMIT_MeshVertex.inl"
